<template>
	<!-- <div style="float: right; margin-bottom: 20px">
		<el-button type="primary" @click="allCheck(0)">全选</el-button>
		<el-button plain @click="allCheck(1)">取消全选</el-button>
	</div> -->
	<el-table ref="tableRef" :data="menuList" border style="width: 100%" :key="tableKey" :span-method="objectSpanMethod" @cell-click="cellClick">
		<el-table-column prop="menu1" label="一级菜单" width="150">
			<template #default="scope">
				<el-checkbox
					v-model="scope.row.menu1.checked"
					:label="scope.row.menu1.name"
					:disabled="readOnly || scope.row.menu1.disabled"
					@change="menu1Change($event, scope.row.menu1)"
					@click.stop
				></el-checkbox>
				<el-icon class="ml10" v-if="scope.row.menu1.children.length > 1 || (scope.row.menu2 && scope.row.menu2.children.length > 1)"
					><ArrowUpBold v-if="scope.row.menu1.packUp" /> <ArrowDownBold v-else
				/></el-icon>
			</template>
		</el-table-column>
		<el-table-column prop="menu2" label="二级菜单" width="200">
			<template #default="scope">
				<el-checkbox
					v-if="scope.row.menu2 && !scope.row.menu1.packUp"
					v-model="scope.row.menu2.checked"
					:label="scope.row.menu2.name"
					:disabled="readOnly || scope.row.menu2.disabled"
					@change="menu2Change($event, scope.row.menu2, scope.row)"
					@click.stop
				></el-checkbox>
				<span v-else-if="scope.row.menu2">......</span>
				<el-icon class="ml10" v-if="scope.row.menu2 && scope.row.menu2.children.length > 1 && !scope.row.menu1.packUp"
					><ArrowUpBold v-if="scope.row.menu2.packUp" /> <ArrowDownBold v-else
				/></el-icon>
			</template>
		</el-table-column>
		<el-table-column prop="menu3" label="操作按钮">
			<template #default="scope">
				<el-checkbox
					v-if="scope.row.menu3 && !scope.row.menu2.packUp && !scope.row.menu1.packUp"
					v-model="scope.row.menu3.checked"
					:disabled="readOnly || scope.row.menu3.disabled"
					:label="scope.row.menu3.name"
					@change="menu3Change($event, scope.row.menu3, scope.row)"
				></el-checkbox>
				<span v-else-if="scope.row.menu3">......</span>
			</template>
		</el-table-column>
	</el-table>
</template>

<script lang="ts" setup>
import { CheckboxValueType, TableColumnCtx } from 'element-plus';
import { ref, watch } from 'vue';
import { Role } from '@/api/interface';
const emit = defineEmits(['checkboxChange']);
const tableRef = ref();
const tableKey = ref(new Date().getTime());

// 生成一个与行数相同的数组记录每一行设置的合并数
// const state = reactive({
//   spanArr: []
// });
// 计算需要合并的数组
let spanData: Array<any[]> = [];
// 设置需要合并的字段
const columnArr = ['menu1', 'menu2', 'menu3'];
const menuList = ref();

const props = defineProps({
	tableData: { type: Array },
	readOnly: { type: Boolean },
});

watch(
	() => props.tableData,
	(val) => {
		menuList.value = [];

		// 拆分数据
		makeMenuList(val);

		// 转换数据
		getSpanData(menuList.value);
	},
	{
		deep: true,
	}
);

// type：0全选 1：取消全选
function allCheck(type: number) {
	menuList.value?.forEach((item: any) => {
		if (!item.menu1.checked) item.menu1.checked = false;
		item.menu1.checked = type === 0;
		emit('checkboxChange', {
			type: item.menu1.type,
			id: item.menu1.id,
			checked: item.menu1.checked,
		});

		if (!item.menu2.checked) item.menu2.checked = false;
		item.menu2.checked = type === 0;
		emit('checkboxChange', {
			type: item.menu2.type,
			id: item.menu2.id,
			checked: item.menu2.checked,
		});

		if (item.menu3) {
			if (!item.menu3.checked) item.menu3.checked = false;
			item.menu3.checked = type === 0;
			emit('checkboxChange', {
				type: item.menu3.type,
				id: item.menu3.id,
				checked: item.menu3.checked,
			});
		}
	});
}

// 根据接口数据转换格式
function makeMenuList(data: any) {
	data?.forEach((item1: any) => {
		if (item1.children.length > 0) {
			item1.children.forEach((item2: any) => {
				if (item2.children.length > 0) {
					item2.children.forEach((item3: any) => {
						menuList.value.push({
							menu1: { ...item1, checked: item1.checked },
							menu2: { ...item2, checked: item2.checked },
							menu3: { ...item3, checked: item3.checked },
						});
					});
				} else {
					menuList.value.push({
						menu1: { ...item1, checked: item1.checked },
						menu2: { ...item2, checked: item2.checked },
						menu3: '',
					});
				}
			});
		} else {
			menuList.value.push({
				menu1: { name: item1.name, ...item1, checked: item1.checked },
				menu2: '',
				menu3: '',
			});
		}
	});
}

const cellClick = (row: any, column: any, cell: HTMLTableCellElement, event: Event) => {
	if (column.property === 'menu3') {
		return;
	}
	row[column.property].packUp = !row[column.property].packUp;
	let packUpData: any[] = [];
	if (row[column.property].packUp) {
		for (let index = 0; index < menuList.value.length; index++) {
			const item = menuList.value[index];
			if (item[column.property].name === row[column.property].name && item[column.property].packUp == undefined) {
				packUpData.push(item);
				menuList.value.splice(index, 1);
				index--;
			}
		}
	} else {
		const index = menuList.value.findIndex((V: any) => V[column.property].name === row[column.property].name);
		menuList.value.splice(index + 1, 0, ...row[column.property].packUpData);
	}
	row[column.property].packUpData = packUpData;
	// 转换数据
	getSpanData(menuList.value);
};

// 一级菜单勾选事件
const menu1Change = (checked: CheckboxValueType, item: any) => {
	emit('checkboxChange', {
		type: item.type,
		id: item.id,
		checked,
	});

	menuList.value.forEach((mItem: any) => {
		// // 一级菜单默认勾上
		// mItem.menu1.checked = true;
		// emit("checkboxChange", {
		//   id: mItem.menu1.id,
		//   checked: true
		// });

		// 勾选一级，把相关的二级都勾上
		if (mItem.menu2.parentId === item.id) {
			mItem.menu2.checked = checked;
			emit('checkboxChange', {
				type: mItem.menu2.type,
				id: mItem.menu2.id,
				checked,
			});
			// 勾选二级，把相关的三级都勾上
			if (mItem.menu3.parentId === mItem.menu2.id) {
				mItem.menu3.checked = checked;
				emit('checkboxChange', {
					type: mItem.menu3.type,
					id: mItem.menu3.id,
					checked,
				});
			}
			// 勾选二级，把隐藏的三级都勾上
			if (mItem.menu2.packUpData?.length) {
				mItem.menu2.packUpData.forEach((mItem3: any) => {
					mItem3.menu3.checked = checked;
					emit('checkboxChange', {
						type: mItem3.menu3.type,
						id: mItem3.menu3.id,
						checked,
					});
				});
			}
		}
	});
	// 勾选二级，把隐藏的二三级都勾上
	if (item.packUpData?.length) {
		item.packUpData.forEach((mItem3: any) => {
			mItem3.menu2.checked = checked;
			emit('checkboxChange', {
				type: mItem3.menu2.type,
				id: mItem3.menu2.id,
				checked,
			});
			mItem3.menu3.checked = checked;
			emit('checkboxChange', {
				type: mItem3.menu3.type,
				id: mItem3.menu3.id,
				checked,
			});
		});
	}
};

// 二级菜单勾选事件
const menu2Change = (checked: CheckboxValueType, item: any, row: any) => {
	emit('checkboxChange', {
		type: item.type,
		id: item.id,
		checked,
	});

	menuList.value.forEach((mItem: any) => {
		// // 一级菜单默认勾上
		// mItem.menu1.checked = true;
		// emit("checkboxChange", {
		//   id: mItem.menu1.id,
		//   checked: true
		// });

		if (checked) {
			// 循环所有数组，如果二级勾上了，一级联动勾上
			menuList.value.forEach((mItem: any) => {
				// emitChange(mItem.menu1.type,mItem.menu1.id, checked as boolean);
				if (item.parentId === mItem.menu1.id) {
					mItem.menu1.checked = true;
					emitChange(mItem.menu1.type, mItem.menu1.id, checked as boolean);
				}
			});
		} else {
			let num = new Set();
			// 循环二级菜单，看有多少个没勾中
			menuList.value.forEach((mItem: any) => {
				if (typeof mItem.menu2.checked !== 'undefined' && !mItem.menu2.checked && mItem.menu2.parentId == row.menu2.parentId) {
					num.add(mItem.menu2.id);
				}
			});
			// 如果二级菜单全部都取消勾选了，一级菜单也取消
			menuList.value.forEach((mItem1: any) => {
				if (mItem1.menu1.id === row.menu2.parentId) {
					if (Array.from(num).length === mItem1.menu1.children.length) {
						mItem1.menu1.checked = false;
						emitChange(mItem1.menu1.type, mItem1.menu1.id, checked as boolean);
					}
				}
			});
		}
		// 勾选二级，把相关的三级都勾上
		if (mItem.menu3.parentId === item.id) {
			mItem.menu3.checked = checked;
			emit('checkboxChange', {
				type: mItem.menu3.type,
				id: mItem.menu3.id,
				checked,
			});
		}
	});
	// 勾选二级，把隐藏的三级都勾上
	if (item.packUpData?.length) {
		item.packUpData.forEach((mItem3: any) => {
			mItem3.menu3.checked = checked;
			emit('checkboxChange', {
				type: mItem3.menu3.type,
				id: mItem3.menu3.id,
				checked,
			});
		});
	}
};

const emitChange = (type: string, id: number, checked: boolean) => {
	emit('checkboxChange', {
		type,
		id,
		checked,
	});
};

// 三级菜单勾选事件
const menu3Change = (checked: CheckboxValueType, item: any, row: any) => {
	item.checked = checked;
	emitChange(item.type, item.id, checked as boolean);

	if (checked) {
		// 循环所有数组，如果三级勾上了，二级联动勾上
		menuList.value.forEach((mItem: any) => {
			if (item.parentId === mItem.menu2.id) {
				mItem.menu2.checked = true;
				emitChange(mItem.menu2.type, mItem.menu2.id, checked as boolean);
				if (mItem.menu2.parentId == mItem.menu1.id) {
					mItem.menu1.checked = true;
					emitChange(mItem.menu1.type, mItem.menu1.id, checked as boolean);
				}
			}
		});
	}
};

// 计算需要合并的单元格
const getSpanData = async (data: any) => {
	spanData = [];
	columnArr.forEach((element) => {
		let contactDot = 0;
		const spanArr: Array<number> = [];
		data.forEach((item: any, index: number) => {
			if (index === 0) {
				spanArr.push(1);
			} else if (item[element].name === data[index - 1][element].name && item[element].parentId === data[index - 1][element].parentId) {
				spanArr[contactDot] += 1;
				spanArr.push(0);
			} else {
				contactDot = index;
				spanArr.push(1);
			}
		});

		spanData.push(spanArr);
		console.log('spanData', spanData);
	});
};

// 合并单元格
const objectSpanMethod = ({
	column,
	rowIndex,
	columnIndex,
}: {
	column: TableColumnCtx<Role.RoleMenuTree>;
	rowIndex: number;
	columnIndex: number;
}) => {
	try {
		if (columnArr.includes(column.property)) {
			if (spanData[columnIndex][rowIndex]) {
				return {
					rowspan: spanData[columnIndex][rowIndex],
					colspan: 1,
				};
			}
			return {
				rowspan: 0,
				colspan: 0,
			};
		}
	} catch (e) {}
	return [];
};
</script>

<style scoped></style>
